<template>
  <div id="canvas-wrapper"><canvas id="canvas"></canvas></div>
</template>
<script>
/* eslint-disable*/
import Tween from 'tween'

export default {
  name: 'CanvasBackground',
  props: {
    isColor: {
      type: Boolean,
      default: true
    }
  },
  mounted () {
    // create points
    const canvas = document.getElementById('canvas')
    const largeHeader = document.getElementById('canvas-wrapper')
    var width = window.innerWidth
    var height = window.innerHeight
    const target = {
      x: width / 2,
      y: height / 1
    }
    var animateHeader = true
    var points = []
    var ctx = canvas.getContext('2d')
    const initHeader = () => {
      let ctx = canvas.getContext('2d')
      canvas.width = width
      canvas.height = height

      // create points
      let point = [];
      for (let x = 0; x < width; x = x + width / 20) {
        for (let y = 0; y < height; y = y + height / 20) {
          let px = x + Math.random() * width / 20;
          let py = y + Math.random() * height / 20;
          let p = {
            x: px,
            originX: px,
            y: py,
            originY: py
          }
          points.push(p)
        }
      }
      // for each point find the 5 closest points
      for (let i = 0; i < points.length; i++) {
        let closest = []
        let p1 = points[i]
        for (let j = 0; j < points.length; j++) {
          let p2 = points[j]
          if (!(p1 === p2)) {
            let placed = false
            for (let k = 0; k < 5; k++) {
              if (!placed) {
                if (closest[k] === undefined) {
                  closest[k] = p2
                  placed = true
                }
              }
            }

            for (let k = 0; k < 5; k++) {
              if (!placed) {
                if (getDistance(p1, p2) < getDistance(p1, closest[k])) {
                  closest[k] = p2
                  placed = true
                }
              }
            }
          }
        }
        p1.closest = closest
      }
      // assign a circle to each point
      for (let i in points) {
        let c = new circle(points[i], 2 + Math.random() * 2, 'rgba(255,255,255,0.3)')
        points[i].circle = c
      }
    }

    // draw circle
    var circle = class {
      constructor (pos, rad, color) {
        this.pos = pos || null
        this.radius = rad || null
        this.color = color || null
      }
      draw () {
        if (!this.active) return
        ctx.beginPath()
        ctx.arc(this.pos.x, this.pos.y, this.radius, 0, 2 * Math.PI, false)
        ctx.fillStyle = 'rgba(156,217,249,' + this.active + ')'
        ctx.fill()
      }
    }
    const listeners = () => {
      if (!('ontouchstart' in window)) {
        window.addEventListener('mousemove', mouseMove)
      }
      window.addEventListener('scroll', scrollCheck)
      window.addEventListener('resize', resize)
    }

    const mouseMove = (e) => {
      let posx = 0
      let posy = 0
      if (e.pageX || e.pageY) {
        posx = e.pageX
        posy = e.pageY
      } else if (e.clientX || e.clientY) {
        posx = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft
        posy = e.clientY + document.body.scrollTop + document.documentElement.scrollTop
      }
      target.x = posx
      target.y = posy
    }
    const scrollCheck = () => {
      if (document.body.scrollTop > height) animateHeader = false
      else animateHeader = true
    }
    const resize = () => {
      let w = window.innerWidth
      let h = window.innerHeight
      largeHeader.style.height = h + 'px'
      canvas.width = w
      canvas.height = h
    }
    const initAnimation = () => {
      animate()
      for (var i in points) {
        shiftPoint(points[i])
      }
    }
    const animate = () => {
      if (animateHeader) {
        ctx.clearRect(0, 0, width, height)
        for (var i in points) {
          // detect points in range
          if (Math.abs(getDistance(target, points[i])) < 4000) {
            points[i].active = 0.3
            points[i].circle.active = 0.6
          } else if (Math.abs(getDistance(target, points[i])) < 20000) {
            points[i].active = 0.1
            points[i].circle.active = 0.3
          } else if (Math.abs(getDistance(target, points[i])) < 40000) {
            points[i].active = 0.02
            points[i].circle.active = 0.1
          } else {
            points[i].active = 0
            points[i].circle.active = 0
          }

          drawLines(points[i])
          points[i].circle.draw()
        }
      }
      requestAnimationFrame(animate)
      Tween.update()
    }
    const shiftPoint = (p) => {
      // var tween = new Tween.Tween(p);
      // console.log(tween);

      var tween = new Tween.Tween(p)
      tween.to(
        { x: p.originX - 50 + Math.random() * 100,
          y: p.originY - 50 + Math.random() * 100
        }, 1000 + 1000 * Math.random()
      ).onComplete(function () {
        shiftPoint(p)
      }).start()
    }
    const drawLines = (p) => {
      if (!p.active) return
      for (var i in p.closest) {
        ctx.beginPath()
        ctx.moveTo(p.x, p.y)
        ctx.lineTo(p.closest[i].x, p.closest[i].y)
        ctx.strokeStyle = 'rgba(156,217,249,' + p.active + ')'
        ctx.stroke()
      }
    }
    const getDistance = (p1, p2) => {
      return Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y - p2.y, 2)
    }
    initHeader()
    initAnimation()
    listeners()
  }
}
</script>

<style>

  #canvas {
    position: fixed;
    z-index: 0;
    top: 0;
    left: 0;
  }

</style>
